package binarySystem;

import java.util.HashSet;
import java.util.Set;

/**
 * 功能描述: 位图: 缓存穿透问题的解决方案
 * 1.记录访问过的ID：可以使用位图来记录所有尝试访问过的ID
 * 2. 结合布隆过滤器：位图可以与布隆过滤器结合使用。布隆过滤器是一种空间效率极高的概率型数据结构，
 * 2024/05/18
 * <p>
 * ZhangYi
 */
public class BitMap {

    private Long[] bits;

    public BitMap(int size) {
        bits = new Long[((size+64) >> 6) ];//size >> 6 是一个位操作，叫做右移操作。它相当于将size除以64 ,+1来保证数组的长度
        for (int i = 0; i < ((size+64) >> 6); i++) {
            this.bits[i]=0L; // 所有的位图都初始化为0,表示不存在
        }
    }

    public void add(int id) {
        bits[id >> 6] |= 1L << (id & 63);
    }

    public void remove(int id){
        bits[id >> 6] &= ~(1L << (id & 63));
    }

    public boolean contains(int id){
        return (bits[id >> 6] & 1L << (id & 63)) != 0;
    }
    public static void main(String[] args) {
        int maxValue = 200;
        int testTimes = 100;
        BitMap defbitMap = defbitMap = new BitMap(maxValue);
        Set<Integer> defbitSet = new HashSet<>();
        for (int i = 0; i < testTimes; i++) {


            int randomValue = (int) (Math.random() * (double) maxValue);
            double device = Math.random();
            if (device < 0.333) {
                defbitMap.add(randomValue);
                defbitSet.add(randomValue);
            } else if (device < 0.666) {
                defbitMap.remove(randomValue);
                defbitSet.remove(randomValue);
            } else {
                if (defbitMap.contains(randomValue) != defbitSet.contains(randomValue)) {
                    System.out.println("集合,位图数据不一致");
//                    break;
                }
            }
        }

        /***
         * 强校验数据不一致的问题
         */
        for (int j = 0; j < maxValue; j++) {
            if (defbitMap.contains(j) != defbitSet.contains(j)) {
                System.out.println(String.format("集合,位图数据不一致%d ",
                                                 j));
            }

            if (defbitMap.contains(j)) {
                System.out.println(String.format("数值%d,在位图中存在",
                                                 j));
            }
        }
        defbitSet.stream().sorted().forEach(res -> {
            System.out.println(String.format("数组%d,在集合中存在",
                                             res));
        });
    }
}
